﻿using System;
using System.Buffers;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace XiAnAirport.BUS.Escalator
{
    public abstract class AbstractEscalator : IEscalator
    {
        public string deviceno;
        public int ChannelIndex;
        public string deviceip;
        public string device_sn;
        public static ClientWebSocket webSocketClient;
        static CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
        static CancellationToken _cancellationToken = _cancellationTokenSource.Token;
        public async Task<bool> ConnectServer(string url)
        {
            bool result = false;
            webSocketClient = await CreateAsync(url);
            if (webSocketClient != null)
            {
                result = true;
                _ = Task.Run(async () =>
                {
                    var buffer = ArrayPool<byte>.Shared.Rent(10240000);
                    try
                    {
                        while (webSocketClient.State == WebSocketState.Open)
                        {
                            //var result = await webSocketClient.ReceiveAsync(buffer, CancellationToken.None);
                            var result = await webSocketClient.ReceiveAsync(buffer, _cancellationToken);
                            if (result.MessageType == WebSocketMessageType.Close)
                            {
                                throw new WebSocketException(WebSocketError.ConnectionClosedPrematurely, result.CloseStatusDescription);
                            }
                            var text = Encoding.UTF8.GetString(buffer.AsSpan(0, result.Count));
                            int index = EscalatorBUS.list.FindIndex(x => x.DecviceNo == deviceno && x.DeviceIP == deviceip && x.ChannelIndex == ChannelIndex && x.DeviceSN == device_sn);
                            if (index > -1)
                            {
                                WebSocket webSocket = EscalatorBUS.list[index].socket;
                                await webSocket.SendAsync(Encoding.UTF8.GetBytes(text), WebSocketMessageType.Text, true, _cancellationToken);
                            }
                        }
                    }
                    finally
                    {
                        ArrayPool<byte>.Shared.Return(buffer);
                    }
                });
            }
            return result;
        }

        /// <summary>
        /// 创建客户端实例
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<ClientWebSocket> CreateAsync(string ServerUri)
        {
            if (webSocketClient != null)
            {
                _cancellationTokenSource.Cancel();
                _cancellationTokenSource = new CancellationTokenSource();
                _cancellationToken = _cancellationTokenSource.Token;
                //await webSocketClient.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
            }
            var webSocket = new ClientWebSocket();
            webSocket.Options.RemoteCertificateValidationCallback = delegate { return true; };

            await webSocket.ConnectAsync(new Uri(ServerUri), CancellationToken.None);
            if (webSocket.State == WebSocketState.Open)
            {
                return webSocket;
            }
            return null;
        }

        public async Task<bool> CloseServer()
        {
            bool result = false;
            if (webSocketClient.State != WebSocketState.Closed)
            {
                await webSocketClient.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
            }
            return result;
        }
    }
}
